/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package MeteoCal.controller;

import MeteoCal.bean.exceptions.IllegalOrphanException;
import MeteoCal.bean.exceptions.NonexistentEntityException;
import MeteoCal.bean.exceptions.PreexistingEntityException;
import MeteoCal.bean.exceptions.RollbackFailureException;
import MeteoCal.entity.Comment;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import MeteoCal.entity.Event;
import MeteoCal.entity.User;
import MeteoCal.entity.Commentwritten;
import java.util.ArrayList;
import java.util.Collection;
import MeteoCal.entity.Warningcomment;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;

/**
 *
 * @author Daniele
 */
public class CommentJpaController implements Serializable {

    public CommentJpaController(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }
    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Comment comment) throws PreexistingEntityException, RollbackFailureException, Exception {
        if (comment.getCommentwrittenCollection() == null) {
            comment.setCommentwrittenCollection(new ArrayList<Commentwritten>());
        }
        if (comment.getWarningcommentCollection() == null) {
            comment.setWarningcommentCollection(new ArrayList<Warningcomment>());
        }
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Event idEvent = comment.getIdEvent();
            if (idEvent != null) {
                idEvent = em.getReference(idEvent.getClass(), idEvent.getIdEvent());
                comment.setIdEvent(idEvent);
            }
            User idAuthor = comment.getIdAuthor();
            if (idAuthor != null) {
                idAuthor = em.getReference(idAuthor.getClass(), idAuthor.getEmail());
                comment.setIdAuthor(idAuthor);
            }
            Collection<Commentwritten> attachedCommentwrittenCollection = new ArrayList<Commentwritten>();
            for (Commentwritten commentwrittenCollectionCommentwrittenToAttach : comment.getCommentwrittenCollection()) {
                commentwrittenCollectionCommentwrittenToAttach = em.getReference(commentwrittenCollectionCommentwrittenToAttach.getClass(), commentwrittenCollectionCommentwrittenToAttach.getCommentwrittenPK());
                attachedCommentwrittenCollection.add(commentwrittenCollectionCommentwrittenToAttach);
            }
            comment.setCommentwrittenCollection(attachedCommentwrittenCollection);
            Collection<Warningcomment> attachedWarningcommentCollection = new ArrayList<Warningcomment>();
            for (Warningcomment warningcommentCollectionWarningcommentToAttach : comment.getWarningcommentCollection()) {
                warningcommentCollectionWarningcommentToAttach = em.getReference(warningcommentCollectionWarningcommentToAttach.getClass(), warningcommentCollectionWarningcommentToAttach.getWarningcommentPK());
                attachedWarningcommentCollection.add(warningcommentCollectionWarningcommentToAttach);
            }
            comment.setWarningcommentCollection(attachedWarningcommentCollection);
            em.persist(comment);
            if (idEvent != null) {
                idEvent.getCommentCollection().add(comment);
                idEvent = em.merge(idEvent);
            }
            if (idAuthor != null) {
                idAuthor.getCommentCollection().add(comment);
                idAuthor = em.merge(idAuthor);
            }
            for (Commentwritten commentwrittenCollectionCommentwritten : comment.getCommentwrittenCollection()) {
                Comment oldCommentOfCommentwrittenCollectionCommentwritten = commentwrittenCollectionCommentwritten.getComment();
                commentwrittenCollectionCommentwritten.setComment(comment);
                commentwrittenCollectionCommentwritten = em.merge(commentwrittenCollectionCommentwritten);
                if (oldCommentOfCommentwrittenCollectionCommentwritten != null) {
                    oldCommentOfCommentwrittenCollectionCommentwritten.getCommentwrittenCollection().remove(commentwrittenCollectionCommentwritten);
                    oldCommentOfCommentwrittenCollectionCommentwritten = em.merge(oldCommentOfCommentwrittenCollectionCommentwritten);
                }
            }
            for (Warningcomment warningcommentCollectionWarningcomment : comment.getWarningcommentCollection()) {
                Comment oldCommentOfWarningcommentCollectionWarningcomment = warningcommentCollectionWarningcomment.getComment();
                warningcommentCollectionWarningcomment.setComment(comment);
                warningcommentCollectionWarningcomment = em.merge(warningcommentCollectionWarningcomment);
                if (oldCommentOfWarningcommentCollectionWarningcomment != null) {
                    oldCommentOfWarningcommentCollectionWarningcomment.getWarningcommentCollection().remove(warningcommentCollectionWarningcomment);
                    oldCommentOfWarningcommentCollectionWarningcomment = em.merge(oldCommentOfWarningcommentCollectionWarningcomment);
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            if (findComment(comment.getIdComment()) != null) {
                throw new PreexistingEntityException("Comment " + comment + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Comment comment) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Comment persistentComment = em.find(Comment.class, comment.getIdComment());
            Event idEventOld = persistentComment.getIdEvent();
            Event idEventNew = comment.getIdEvent();
            User idAuthorOld = persistentComment.getIdAuthor();
            User idAuthorNew = comment.getIdAuthor();
            Collection<Commentwritten> commentwrittenCollectionOld = persistentComment.getCommentwrittenCollection();
            Collection<Commentwritten> commentwrittenCollectionNew = comment.getCommentwrittenCollection();
            Collection<Warningcomment> warningcommentCollectionOld = persistentComment.getWarningcommentCollection();
            Collection<Warningcomment> warningcommentCollectionNew = comment.getWarningcommentCollection();
            List<String> illegalOrphanMessages = null;
            for (Commentwritten commentwrittenCollectionOldCommentwritten : commentwrittenCollectionOld) {
                if (!commentwrittenCollectionNew.contains(commentwrittenCollectionOldCommentwritten)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Commentwritten " + commentwrittenCollectionOldCommentwritten + " since its comment field is not nullable.");
                }
            }
            for (Warningcomment warningcommentCollectionOldWarningcomment : warningcommentCollectionOld) {
                if (!warningcommentCollectionNew.contains(warningcommentCollectionOldWarningcomment)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Warningcomment " + warningcommentCollectionOldWarningcomment + " since its comment field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (idEventNew != null) {
                idEventNew = em.getReference(idEventNew.getClass(), idEventNew.getIdEvent());
                comment.setIdEvent(idEventNew);
            }
            if (idAuthorNew != null) {
                idAuthorNew = em.getReference(idAuthorNew.getClass(), idAuthorNew.getEmail());
                comment.setIdAuthor(idAuthorNew);
            }
            Collection<Commentwritten> attachedCommentwrittenCollectionNew = new ArrayList<Commentwritten>();
            for (Commentwritten commentwrittenCollectionNewCommentwrittenToAttach : commentwrittenCollectionNew) {
                commentwrittenCollectionNewCommentwrittenToAttach = em.getReference(commentwrittenCollectionNewCommentwrittenToAttach.getClass(), commentwrittenCollectionNewCommentwrittenToAttach.getCommentwrittenPK());
                attachedCommentwrittenCollectionNew.add(commentwrittenCollectionNewCommentwrittenToAttach);
            }
            commentwrittenCollectionNew = attachedCommentwrittenCollectionNew;
            comment.setCommentwrittenCollection(commentwrittenCollectionNew);
            Collection<Warningcomment> attachedWarningcommentCollectionNew = new ArrayList<Warningcomment>();
            for (Warningcomment warningcommentCollectionNewWarningcommentToAttach : warningcommentCollectionNew) {
                warningcommentCollectionNewWarningcommentToAttach = em.getReference(warningcommentCollectionNewWarningcommentToAttach.getClass(), warningcommentCollectionNewWarningcommentToAttach.getWarningcommentPK());
                attachedWarningcommentCollectionNew.add(warningcommentCollectionNewWarningcommentToAttach);
            }
            warningcommentCollectionNew = attachedWarningcommentCollectionNew;
            comment.setWarningcommentCollection(warningcommentCollectionNew);
            comment = em.merge(comment);
            if (idEventOld != null && !idEventOld.equals(idEventNew)) {
                idEventOld.getCommentCollection().remove(comment);
                idEventOld = em.merge(idEventOld);
            }
            if (idEventNew != null && !idEventNew.equals(idEventOld)) {
                idEventNew.getCommentCollection().add(comment);
                idEventNew = em.merge(idEventNew);
            }
            if (idAuthorOld != null && !idAuthorOld.equals(idAuthorNew)) {
                idAuthorOld.getCommentCollection().remove(comment);
                idAuthorOld = em.merge(idAuthorOld);
            }
            if (idAuthorNew != null && !idAuthorNew.equals(idAuthorOld)) {
                idAuthorNew.getCommentCollection().add(comment);
                idAuthorNew = em.merge(idAuthorNew);
            }
            for (Commentwritten commentwrittenCollectionNewCommentwritten : commentwrittenCollectionNew) {
                if (!commentwrittenCollectionOld.contains(commentwrittenCollectionNewCommentwritten)) {
                    Comment oldCommentOfCommentwrittenCollectionNewCommentwritten = commentwrittenCollectionNewCommentwritten.getComment();
                    commentwrittenCollectionNewCommentwritten.setComment(comment);
                    commentwrittenCollectionNewCommentwritten = em.merge(commentwrittenCollectionNewCommentwritten);
                    if (oldCommentOfCommentwrittenCollectionNewCommentwritten != null && !oldCommentOfCommentwrittenCollectionNewCommentwritten.equals(comment)) {
                        oldCommentOfCommentwrittenCollectionNewCommentwritten.getCommentwrittenCollection().remove(commentwrittenCollectionNewCommentwritten);
                        oldCommentOfCommentwrittenCollectionNewCommentwritten = em.merge(oldCommentOfCommentwrittenCollectionNewCommentwritten);
                    }
                }
            }
            for (Warningcomment warningcommentCollectionNewWarningcomment : warningcommentCollectionNew) {
                if (!warningcommentCollectionOld.contains(warningcommentCollectionNewWarningcomment)) {
                    Comment oldCommentOfWarningcommentCollectionNewWarningcomment = warningcommentCollectionNewWarningcomment.getComment();
                    warningcommentCollectionNewWarningcomment.setComment(comment);
                    warningcommentCollectionNewWarningcomment = em.merge(warningcommentCollectionNewWarningcomment);
                    if (oldCommentOfWarningcommentCollectionNewWarningcomment != null && !oldCommentOfWarningcommentCollectionNewWarningcomment.equals(comment)) {
                        oldCommentOfWarningcommentCollectionNewWarningcomment.getWarningcommentCollection().remove(warningcommentCollectionNewWarningcomment);
                        oldCommentOfWarningcommentCollectionNewWarningcomment = em.merge(oldCommentOfWarningcommentCollectionNewWarningcomment);
                    }
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = comment.getIdComment();
                if (findComment(id) == null) {
                    throw new NonexistentEntityException("The comment with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Comment comment;
            try {
                comment = em.getReference(Comment.class, id);
                comment.getIdComment();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The comment with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Commentwritten> commentwrittenCollectionOrphanCheck = comment.getCommentwrittenCollection();
            for (Commentwritten commentwrittenCollectionOrphanCheckCommentwritten : commentwrittenCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Comment (" + comment + ") cannot be destroyed since the Commentwritten " + commentwrittenCollectionOrphanCheckCommentwritten + " in its commentwrittenCollection field has a non-nullable comment field.");
            }
            Collection<Warningcomment> warningcommentCollectionOrphanCheck = comment.getWarningcommentCollection();
            for (Warningcomment warningcommentCollectionOrphanCheckWarningcomment : warningcommentCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Comment (" + comment + ") cannot be destroyed since the Warningcomment " + warningcommentCollectionOrphanCheckWarningcomment + " in its warningcommentCollection field has a non-nullable comment field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Event idEvent = comment.getIdEvent();
            if (idEvent != null) {
                idEvent.getCommentCollection().remove(comment);
                idEvent = em.merge(idEvent);
            }
            User idAuthor = comment.getIdAuthor();
            if (idAuthor != null) {
                idAuthor.getCommentCollection().remove(comment);
                idAuthor = em.merge(idAuthor);
            }
            em.remove(comment);
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Comment> findCommentEntities() {
        return findCommentEntities(true, -1, -1);
    }

    public List<Comment> findCommentEntities(int maxResults, int firstResult) {
        return findCommentEntities(false, maxResults, firstResult);
    }

    private List<Comment> findCommentEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Comment.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Comment findComment(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Comment.class, id);
        } finally {
            em.close();
        }
    }

    public int getCommentCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Comment> rt = cq.from(Comment.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
